Condições e fatores

Aula 14, M2

Carolina Musso

Sala de Situação - UnB

Esta semana

Aula 14

  • As funções if(), if_else() e case_when()

  • Pacotw forcats

Aula 24 - Tabela

  • Finalizando noções sobre o pacote flextable()

Leituras para aprofundamento

if else

As estruturas if e else servem para executarmos um código apenas se uma condição (teste lógico) for satisfeita.

A estrutura geral de um if statement é como a seguir:

if (condition) {
  # código a executar se a condição for verdadeira (retornar TRUE)
} else {
  # código a executar se a condição for falsa (retornar FALSE)
}

Exemplo

  • Vamos tentar entender a lógica geral
x <- 2

if (x == 1) {         
  Sys.time()
}
  • Nada acontece
if (x == 2) {         
  Sys.time()
}
[1] "2023-10-30 12:57:56 -03"

if else

x <- 2

if (x == 1) {         
  Sys.time()
} else {
  "x não é 1"
}
[1] "x não é 1"

É muito útil mas…

  • Acho que ainda um pouco avançado para esse momento.
  • Muito útil para escrever as próprias funções
minha_funcao <- function(x) {
  if (x == 1) {         
  Sys.time()
} else {
  "x não é 1"
}
} 
  
minha_funcao(2)
[1] "x não é 1"
minha_funcao(1)
[1] "2023-10-30 12:57:56 -03"
  • Nós vamos focar em formas mais “enxuta”: ifelse() e case_when()

Criando novas variáveis

  • Com o mutate(), lembram?
  • Agora juntamente com um ifelse() ou case_when()
dados %>% 
  mutate(nova_var = ifelse(condição, "Caso afirmativo", "Caso negativo") )

Um exemplo

dados_debola %>% 
  mutate(Port_Hospital = ifelse(hospital == "Port Hospital", "Sim", "Não")) %>% 
  select(hospital, Port_Hospital) %>% 
  head(10)
# A tibble: 10 × 2
   hospital                             Port_Hospital
   <chr>                                <chr>        
 1 Other                                Não          
 2 Missing                              Não          
 3 St. Mark's Maternity Hospital (SMMH) Não          
 4 Port Hospital                        Sim          
 5 Military Hospital                    Não          
 6 Port Hospital                        Sim          
 7 Missing                              Não          
 8 Missing                              Não          
 9 Missing                              Não          
10 Missing                              Não          

Outro exemplo

dados_debola %>% 
  mutate(Fase = ifelse(age_years < 18, "Criança", 
                       ifelse(age_years > 60, "Idoso", "Adulto"))) %>% 
  select(age_years, Fase ) %>% 
  head(10)
# A tibble: 10 × 2
   age_years Fase   
       <dbl> <chr>  
 1         2 Criança
 2         3 Criança
 3        56 Adulto 
 4        18 Adulto 
 5         3 Criança
 6        16 Criança
 7        16 Criança
 8         0 Criança
 9        61 Idoso  
10        27 Adulto 
  • mas

Recomendação nesse caso

  • A função cut()
  • Ótima para discretizar variáveis quantitativas
dados_debola %>% 
  mutate(Faixa = cut(age_years, breaks=c(0, 20, 40, 60, 80, 100),
                    right=F) )%>% 
  select(age_years, Faixa ) %>% 
  head(10)
# A tibble: 10 × 2
   age_years Faixa  
       <dbl> <fct>  
 1         2 [0,20) 
 2         3 [0,20) 
 3        56 [40,60)
 4        18 [0,20) 
 5         3 [0,20) 
 6        16 [0,20) 
 7        16 [0,20) 
 8         0 [0,20) 
 9        61 [60,80)
10        27 [20,40)
  • Posso mudar os labels
dados_debola %>% 
  mutate(Faixa = cut(age_years, breaks=c(0, 20,  40,  60,  80, 100),
                    labels= c("< 20 anos", "21-40 anos", "31-60 anos", 
                              "61-80 anos", "> 80 anos"), 
                    right=F) )%>% 
  select(age_years, Faixa ) %>% 
  head(10)
# A tibble: 10 × 2
   age_years Faixa     
       <dbl> <fct>     
 1         2 < 20 anos 
 2         3 < 20 anos 
 3        56 31-60 anos
 4        18 < 20 anos 
 5         3 < 20 anos 
 6        16 < 20 anos 
 7        16 < 20 anos 
 8         0 < 20 anos 
 9        61 61-80 anos
10        27 21-40 anos

Ou case_when()

dados_debola %>% 
  mutate(idade_anos = case_when(
       age_unit == "years"  ~ age,       
       age_unit == "months" ~ age/12) ) %>% 
  select(age_unit, age, idade_anos) %>% 
  group_by(age_unit) %>% 
  sample_n(3)
# A tibble: 6 × 3
# Groups:   age_unit [2]
  age_unit   age idade_anos
  <chr>    <dbl>      <dbl>
1 months       9       0.75
2 months      24       2   
3 months       6       0.5 
4 years       29      29   
5 years       15      15   
6 years       11      11   
dados_debola %>% 
  mutate(Desfecho = case_when(
       outcome == "Death"  ~ "Óbito",       
       outcome == "Recover" ~ "Recuperado",
      .default  = "Investigar")) %>% 
  select(outcome, Desfecho) %>% 
  group_by(outcome) %>% 
  sample_n(3)
# A tibble: 9 × 2
# Groups:   outcome [3]
  outcome Desfecho  
  <chr>   <chr>     
1 Death   Óbito     
2 Death   Óbito     
3 Death   Óbito     
4 Recover Recuperado
5 Recover Recuperado
6 Recover Recuperado
7 <NA>    Investigar
8 <NA>    Investigar
9 <NA>    Investigar

Fatores

Leituras para aprofundamento

Fatores

  • Variáveis do tipo caractere mas…

    • Que têm uma ordem inata
  • Variável qualitativa/categórica ordinal

  • Possui níveis (não necessariamente alfabético).

Ordem do R

rm(list=ls()) # só para limpar o ambiente
pacman::p_load(tidyverse, rio, janitor)

linelist <- import("Exercicios/linelist_cleaned.rds")
linelist <- linelist %>% 
  mutate(delay_cat = case_when(
    # criteria                                   # new value if TRUE
    days_onset_hosp < 2                        ~ "< 2 dias",
    days_onset_hosp >= 2 & days_onset_hosp < 5 ~ "2-5 dias",
    days_onset_hosp >= 5                       ~ "> 5 dias")) %>% 
  filter(!is.na(delay_cat)) %>% 
  select(hospital, date_onset, days_onset_hosp, delay_cat, ct_blood)
str(linelist)
'data.frame':   5632 obs. of  5 variables:
 $ hospital       : chr  "Other" "Missing" "St. Mark's Maternity Hospital (SMMH)" "Port Hospital" ...
 $ date_onset     : Date, format: "2014-05-13" "2014-05-13" ...
 $ days_onset_hosp: num  2 1 2 2 1 1 2 1 1 2 ...
 $ delay_cat      : chr  "2-5 dias" "< 2 dias" "2-5 dias" "2-5 dias" ...
 $ ct_blood       : num  22 22 21 23 23 21 21 22 22 22 ...
ggplot(data = linelist)+
  geom_bar(  #semelhante ao geom_hist mas para categóricas
    mapping = aes(x = delay_cat))+
  theme_classic(base_size = 16)

Mudar a ordem

Para ver as categorias que tenho:

#unique(dados$nome_coluna) estrutura
unique(linelist$delay_cat)
[1] "2-5 dias" "< 2 dias" "> 5 dias"
  • Caso ela já fosse um fator:
unique(linelist_fator$delay_cat)
[1] 2-5 dias < 2 dias > 5 dias
Levels: < 2 dias > 5 dias 2-5 dias
str(linelist_fator)
'data.frame':   5632 obs. of  5 variables:
 $ hospital       : chr  "Other" "Missing" "St. Mark's Maternity Hospital (SMMH)" "Port Hospital" ...
 $ date_onset     : Date, format: "2014-05-13" "2014-05-13" ...
 $ days_onset_hosp: num  2 1 2 2 1 1 2 1 1 2 ...
 $ delay_cat      : Factor w/ 3 levels "< 2 dias","> 5 dias",..: 3 1 3 3 1 1 3 1 1 3 ...
 $ ct_blood       : num  22 22 21 23 23 21 21 22 22 22 ...
  • Pronto, agora que sei o que tem, posso reordenar.

Reordenando

linelist_fator <- linelist %>%
  mutate(delay_cat = fct_relevel(delay_cat, 
                                 "< 2 dias", 
                                 "2-5 dias","> 5 dias"))

unique(linelist_fator$delay_cat)
[1] 2-5 dias < 2 dias > 5 dias
Levels: < 2 dias 2-5 dias > 5 dias
  • As funções começam com “fct_”…

  • A variável não precisa ser fator de antemão, mas automaticamente virará.

linelist_fator <- linelist %>%
  mutate(delay_cat = factor(delay_cat, 
                            levels=c("< 2 dias", 
                                 "2-5 dias","> 5 dias")))

Como ficou

ggplot(linelist_fator )+
  geom_bar(mapping = aes(x = delay_cat))+
  theme_classic(base_size = 16)

Diretamente no gráfico

ggplot(data = linelist)+
  geom_bar(mapping = aes(x = fct_relevel(delay_cat, 
                    c("< 2 dias", 
                                 "2-5 dias","> 5 dias"))))+
  theme_classic(base_size = 16)

  • Vocês já sabem mudar os eixos!

Outras formas

  • Mudar apenas uma posição.
linelist %>% 
  mutate(delay_cat = fct_relevel(delay_cat, "< 2 dias", after = 1)) %>% 
  tabyl(delay_cat)
 delay_cat    n   percent
  > 5 dias  602 0.1068892
  < 2 dias 2990 0.5308949
  2-5 dias 2040 0.3622159
  • Novidade pra vocês: função tabyl() pacote janitor.

Pela frequência:

linelist %>% 
ggplot(aes(x = fct_infreq(delay_cat)))+
  geom_bar()+
  labs(x = "Oportunidade sintomas-internação (dias)",
       title = "Ordenado por frequência decrescente")+
  theme_classic(base_size = 16)

linelist %>% 
ggplot(data = , aes(x = fct_rev(fct_infreq(delay_cat))))+
  geom_bar()+
  labs(x = "Oportunidade sintomas-internação (dias)",
       title = "Ordenado por frequência crescente")+
  theme_classic(base_size = 16)

Pela frequência

linelist %>% 
ggplot( )+
  geom_boxplot(aes(x = delay_cat,y = ct_blood))+
  theme_classic(base_size = 16)

linelist %>% 
ggplot( )+
  geom_boxplot(
    aes(x = fct_reorder(delay_cat, ct_blood, "median"),
        y = ct_blood))+
  theme_classic(base_size = 16)

Número de níveis

linelist %>% 
  mutate(delay_cat = fct_expand(delay_cat,
                                "Não adimitido", 
                                "Transferido")) %>%
tabyl(delay_cat) #pacote janitor
     delay_cat    n   percent
      < 2 dias 2990 0.5308949
      > 5 dias  602 0.1068892
      2-5 dias 2040 0.3622159
 Não adimitido    0 0.0000000
   Transferido    0 0.0000000
linelist %>% 
  mutate(delay_cat = fct_drop(delay_cat)) %>% 
  tabyl(delay_cat)
 delay_cat    n   percent
  < 2 dias 2990 0.5308949
  > 5 dias  602 0.1068892
  2-5 dias 2040 0.3622159

Agrupar em “outros”

linelist %>% 
 mutate(hospital = fct_other(                      
    hospital,
    keep = c("Port Hospital", "Central Hospital"),  
    other_level = "Outros")) %>% 
  tabyl(hospital)    
         hospital    n    percent
 Central Hospital  436 0.07741477
    Port Hospital 1687 0.29953835
           Outros 3509 0.62304688
linelist %>% 
mutate(hospital = fct_lump(                     
    hospital,
    n = 2,                                           
    other_level = "Outros")) %>%           
  tabyl(hospital)  
      hospital    n   percent
       Missing 1398 0.2482244
 Port Hospital 1687 0.2995384
        Outros 2547 0.4522372
 linelist %>% 
  mutate(hospital = fct_lump(hospital,
    n = 2, other_level = "Outros")) %>%     
  mutate(hospital = fct_recode(
    hospital,
    "Faltante" = "Missing")) %>% 
  tabyl(hospital)
      hospital    n   percent
      Faltante 1398 0.2482244
 Port Hospital 1687 0.2995384
        Outros 2547 0.4522372

Obrigada!